package com.mobileares.midp.widgets.client.textbox2.widget;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.*;
import com.mobileares.midp.widgets.client.list.ListItem;
import com.mobileares.midp.widgets.client.list.ListWidget;
import com.mobileares.midp.widgets.client.utils.CodeModel;
import com.mobileares.midp.widgets.client.utils.ICodeProvider;

/**
 * Created by IntelliJ IDEA.
 * User: Tom
 * Date: 2011-4-8
 * Time: 14:57:55
 * To change this template use File | Settings | File Templates.
 */
public class ListBox extends Composite {
    private TextBox box = new TextBox() {
        @Override
        public void onBrowserEvent(Event event) {
            if (event.getTypeInt() == Event.ONBLUR) {
                if (pop.isShowing()) return;
            }
            super.onBrowserEvent(event);
        }
    };
    private PopupPanel pop = new PopupPanel(true);
    private ListWidget listWidget;

    private Object value = null;
    private ICodeProvider codeProvider = new ICodeProvider<CodeModel>() {
        public Object getUserObject(CodeModel ob) {
            return ob.getCode();
        }

        public Widget getWidget(CodeModel ob) {
            return new Label(ob.getText());
        }

        public String getText(CodeModel ob) {
            return ob.getText();
        }

        public String getCode(CodeModel ob) {
            return ob.getCode();
        }
    };

    public ListBox() {
        box.setStyleName("textbox-list");
        box.setReadOnly(true);
        listWidget = new ListWidget();
        listWidget.addStyleName("textbox-list-pop");
        listWidget.setProvider(codeProvider);
        DOM.setStyleAttribute(pop.getElement(), "zIndex", "1001");
        pop.add(listWidget);
        initWidget(box);
        init();
    }

    public void setCodeProvider(ICodeProvider codeProvider) {
        this.codeProvider = codeProvider;
        listWidget.setProvider(codeProvider);
    }

    private void init() {
        box.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                pop.setPopupPosition(getAbsoluteLeft(), getAbsoluteTop() + 26);
                pop.show();
                DeferredCommand.addCommand(new Command() {
                    public void execute() {
//                        listWidget.setFocus(true);
                        listWidget.setSelected(value, false);
                    }
                });
            }
        });
        listWidget.addSelectionHandler(new SelectionHandler<ListItem>() {
            public void onSelection(SelectionEvent<ListItem> listItemSelectionEvent) {
                Object ob = listItemSelectionEvent.getSelectedItem().getUserObject();
                value = codeProvider.getUserObject(ob);
                pop.hide();
                setValue(value);
            }
        });
    }

    public Object getValue() {
        return value;
    }

    public void clear() {
        listWidget.removeAll();
    }


    public void setValue(Object value) {
        this.value = value;
        ListItem item = listWidget.getItemByCode(value);
        if (item == null) box.setValue(value == null ? "" : (String) value,true);
        else
            box.setValue(codeProvider.getText(item.getUserObject()),true);
        box.setFocus(true);

    }

    public void addItem(Object ob) {
        listWidget.addItem(ob);
    }

    public void addItem(final String text, String code) {
        ListItem item = new ListItem(new CodeModel(text, code));
        listWidget.addItem(item);
    }

    public Widget getWidget() {
        return box;
    }
}
